package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.common.utils.CountUtil;
import com.nineclock.model.dto.DepartmentOrUserSimpleDTO;
import com.nineclock.model.dto.SysDepartmentDTO;
import com.nineclock.model.pojo.SysCompanyUser;
import com.nineclock.model.pojo.SysDepartment;
import com.nineclock.system.mapper.SysCompanyUserMapper;
import com.nineclock.system.mapper.SysDepartmentMapper;
import com.nineclock.system.service.SysCompanyUserService;
import com.nineclock.system.service.SysDepartmentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SysDepartmentServiceImpl implements SysDepartmentService {
    @Autowired
    SysDepartmentMapper sysDepartmentMapper;
    @Autowired
    SysCompanyUserMapper sysCompanyUserMapper;
    @Override
    public List<SysDepartmentDTO> queryDepartmentList() {

        Long companyId = CurrentUserHolder.get().getCompanyId();
        List<SysDepartmentDTO> sysDepartmentDTOS = queryChildrenDepartmentList(companyId, 0L);

        return sysDepartmentDTOS;

    }

    @Override
    public void addDepartment(SysDepartmentDTO sysDepartmentDTO) {

        //健壮性判断
        if(sysDepartmentDTO == null || StrUtil.isEmpty(sysDepartmentDTO.getName()) || sysDepartmentDTO.getParent().getId() == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //获取当前登录用户, 企业ID
        Long companyId = CurrentUserHolder.get().getCompanyId();
        Long companyUserId = CurrentUserHolder.get().getCompanyUserId();

        //组装数据
        SysDepartment sysDepartment = new SysDepartment();
        sysDepartment.setName(sysDepartmentDTO.getName());
        sysDepartment.setParentId(sysDepartmentDTO.getParent().getId());
        sysDepartment.setCompanyId(companyId);
        sysDepartment.setUserId(companyUserId);

        //保存部门
        sysDepartmentMapper.insert(sysDepartment);
    }

    @Override
    public List<Long> queryDepartmentIds() {

        LambdaQueryWrapper<SysDepartment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
        wrapper.eq(SysDepartment::getParentId,0L);
        List<SysDepartment> sysDepartments = sysDepartmentMapper.selectList(wrapper);
        if (CollectionUtil.isNotEmpty(sysDepartments)) {

            List<Long> list = sysDepartments.stream().map(sysDepartment -> {
                return sysDepartment.getId();
            }).collect(Collectors.toList());
            return list;
        }
        return new ArrayList<>();
    }

    @Override
    public Integer queryUserCountByDepartmentId(List<Long> departmentIds) {

        if (departmentIds==null) {
            return 0;
        }
        List<Long> Ids = new ArrayList<>();
        for (Long departmentId : departmentIds) {
            Ids.add(departmentId);

            this.queryChildDepartmentIdByParentId(Ids, departmentId);
        }

        LambdaQueryWrapper<SysCompanyUser> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
        queryWrapper.in(SysCompanyUser::getDepartmentId, Ids);
        queryWrapper.eq(SysCompanyUser::getEnable, 1);
        Integer count = sysCompanyUserMapper.selectCount(queryWrapper);
        return count;

    }

    @Override
    public List<DepartmentOrUserSimpleDTO> querySimleDepartment(Long departmentId, Integer includeMember) {
        if (departmentId==null||includeMember==null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        List<DepartmentOrUserSimpleDTO> resultList = new ArrayList<>();
        LambdaQueryWrapper<SysDepartment> sysDepartmentLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysDepartmentLambdaQueryWrapper.eq(SysDepartment::getCompanyId,CurrentUserHolder.get().getCompanyId());
        sysDepartmentLambdaQueryWrapper.eq(SysDepartment::getParentId,departmentId);
        List<SysDepartment> sysDepartments = sysDepartmentMapper.selectList(sysDepartmentLambdaQueryWrapper);
        if (CollectionUtil.isNotEmpty(sysDepartments)) {
            List<DepartmentOrUserSimpleDTO> departmentOrUserSimpleDTOList = sysDepartments.stream().map(sysDepartment -> {
                DepartmentOrUserSimpleDTO departmentOrUserSimpleDTO = new DepartmentOrUserSimpleDTO();
                departmentOrUserSimpleDTO.setId(sysDepartment.getId());
                departmentOrUserSimpleDTO.setName(sysDepartment.getName());
                departmentOrUserSimpleDTO.setType(1);
                return departmentOrUserSimpleDTO;
            }).collect(Collectors.toList());
            resultList.addAll(departmentOrUserSimpleDTOList);
        }

        LambdaQueryWrapper<SysCompanyUser> sysCompanyUserQw = new LambdaQueryWrapper<>();
        sysCompanyUserQw.eq(SysCompanyUser::getCompanyId,CurrentUserHolder.get().getCompanyId());
        sysCompanyUserQw.eq(SysCompanyUser::getDepartmentId,departmentId);
        List<SysCompanyUser> sysCompanyUsers = sysCompanyUserMapper.selectList(sysCompanyUserQw);
        if (CollectionUtil.isNotEmpty(sysCompanyUsers)) {
            List<DepartmentOrUserSimpleDTO> simpleDTOList = sysCompanyUsers.stream().map(sysCompanyUser -> {
                DepartmentOrUserSimpleDTO simpleDTO = new DepartmentOrUserSimpleDTO();
                simpleDTO.setId(sysCompanyUser.getId());
                simpleDTO.setName(sysCompanyUser.getUserName());
                simpleDTO.setType(2);
                return simpleDTO;
            }).collect(Collectors.toList());
            resultList.addAll(simpleDTOList);
        }
        return resultList;
    }

    @Override
    public List<Long> queryDepartmentsByUserId(Long companyUserId) {
        List<Long> depIds = new ArrayList<>();
        LambdaQueryWrapper<SysCompanyUser> sysCompanyUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysCompanyUserLambdaQueryWrapper.eq(SysCompanyUser::getId,companyUserId);
        sysCompanyUserLambdaQueryWrapper.eq(SysCompanyUser::getCompanyId,CurrentUserHolder.get().getCompanyId());
        SysCompanyUser sysCompanyUser = sysCompanyUserMapper.selectOne(sysCompanyUserLambdaQueryWrapper);
        if (sysCompanyUser!=null) {
            Long departmentId = sysCompanyUser.getDepartmentId();
            depIds.add(departmentId);

            while (true){
                SysDepartment sysDepartment = sysDepartmentMapper.selectById(departmentId);
                Long parentId = sysDepartment.getParentId();
                if (parentId!=null&&parentId!=0) {
                    depIds.add(parentId);
                    departmentId = parentId;
                }else {
                    break;
                }
            }
        }
        return depIds;
    }

    /**
     * 查询子部门id
     * @param ids
     * @param departmentId
     */
    private void queryChildDepartmentIdByParentId(List<Long> ids, Long departmentId) {

        LambdaQueryWrapper<SysDepartment> sysDepartmentLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysDepartmentLambdaQueryWrapper.eq(SysDepartment::getCompanyId,CurrentUserHolder.get().getCompanyId());
        sysDepartmentLambdaQueryWrapper.eq(SysDepartment::getParentId,departmentId);

        List<SysDepartment> sysDepartments = sysDepartmentMapper.selectList(sysDepartmentLambdaQueryWrapper);
        if (CollectionUtil.isNotEmpty(sysDepartments)) {
            List<Long> Ids = sysDepartments.stream().map(sysDepartment -> {
                return sysDepartment.getId();
            }).collect(Collectors.toList());
            ids.addAll(Ids);
            for (Long id : Ids) {
                this.queryChildDepartmentIdByParentId(ids,id);
            }
        }
    }

    private List<SysDepartmentDTO> queryChildrenDepartmentList(Long companyId, Long parentId) {
        LambdaQueryWrapper<SysDepartment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDepartment::getCompanyId, companyId);
        queryWrapper.eq(SysDepartment::getParentId, parentId);
        List<SysDepartment> selectList = sysDepartmentMapper.selectList(queryWrapper);
        if (CollectionUtil.isEmpty(selectList)) {
            return new ArrayList<SysDepartmentDTO>();
        }

        List<SysDepartmentDTO> sysDepartmentDTOS = BeanHelper.copyWithCollection(selectList, SysDepartmentDTO.class);
        for (SysDepartmentDTO sysDepartmentDTO : sysDepartmentDTOS) {
            sysDepartmentDTO.setChildren(queryChildrenDepartmentList(companyId, sysDepartmentDTO.getId()));
        }
        return sysDepartmentDTOS;
    }
}
